#pragma once
#include <iostream>
#include <functional>
#include "fields.hpp"
#include <memory>
namespace zyb_rpc
{
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage() {}

        virtual void setId(const std::string &id) { _rid = id; }

        virtual std::string rid() { return _rid; }

        virtual void setMType(MType mtype) { _mtype = mtype; }

        virtual MType mtype() { return _mtype; }

        virtual std::string serialize() = 0;

        virtual bool unserialize(const std::string &msg) = 0;

        virtual bool check() = 0; // 校验消息是否完整

    private:
        MType _mtype;
        std::string _rid;
    };
    // 缓冲区的
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;

        // 返回当前缓冲区中可读取的字节大小
        virtual size_t readableSize() = 0;

        // 查看缓冲区前4个字节并转换为int32_t 尝试读4个字节数据
        virtual int32_t peekInt32() = 0;

        // 从缓冲区中删除前4个字节的数据
        virtual void retrieveInt32() = 0;

        // 从缓冲区中读取4个字节并转换为int32_t，同时移动读指针
        // peekInt32 + retrieveInt32 = readInt32
        virtual int32_t readInt32() = 0;

        // 从缓冲区中读取指定长度的字符串，并从缓冲区中删除这些数据
        virtual std::string retrieveAsString(size_t len) = 0;
    };

    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;
        // 是否能够处理
        virtual bool canProcessed(const BaseBuffer::ptr &buf) = 0;
        // 如果可以处理，给个buf 回一个msg
        virtual bool onMessage(const BaseBuffer::ptr &buf, BaseMessage::ptr &msg) = 0;
        // 序列化msg
        virtual std::string serialize(const BaseMessage::ptr &msg) = 0;
    };
    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        virtual void send(const BaseMessage::ptr &msg) = 0; // 发送msg
        virtual void shutdown() = 0;                        // 关闭连接
        virtual bool connected() = 0;                       // 是否连接
    };

    using ConnectionCallback = std::function<void(const BaseConnection::ptr &)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr &)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr &, BaseMessage::ptr &)>;
    // 服务端
    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;
        virtual void setConnectionCallback(const ConnectionCallback &cb) // 连接建立成功
        {
            _cb_connection = cb;
        }
        virtual void setCloseCallback(const CloseCallback &cb) // 关闭连接
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb) // 消息来的时候
        {
            _cb_message = cb;
        }
        virtual void start() = 0; // 启动服务器

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
    // 客户端
    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;
        virtual void setConnectionCallback(const ConnectionCallback &cb) // 连接建立成功
        {
            _cb_connection = cb;
        }
        virtual void setCloseCallback(const CloseCallback &cb) // 关闭连接
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb) // 消息来的时候
        {
            _cb_message = cb;
        }
        virtual void connect() = 0;                      // 连接服务器
        virtual void shutdown() = 0;                     // 关闭连接
        virtual bool send(const BaseMessage::ptr &) = 0; // 发送消息
        virtual BaseConnection::ptr connection() = 0;    // 获取连接
        virtual bool connected() = 0;                    // 是否连接

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
}